package com.abhinav;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class ProducerConsumerPattern {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// Creating shared object
		BlockingQueue<Integer> sharedQueue = new LinkedBlockingQueue<Integer>();

		// Creating producer & consumer thread
		Thread prodThread = new Thread(new Producer(sharedQueue));
		Thread consThread = new Thread(new Consumer(sharedQueue));

		// Starting producer and Consumer thread
		prodThread.start();
		consThread.start();

//		ExecutorService exec1 = Executors.newSingleThreadExecutor();
//		ExecutorService	exec2 = Executors.newCachedThreadPool();
//		exec1.execute(new Producer(sharedQueue));
//		exec1.execute(new Consumer(sharedQueue));
//		
//		exec1.shutdown();
	}

}

class Producer implements Runnable {

	private final BlockingQueue<Integer> sharedQueue;

	public Producer(BlockingQueue<Integer> sharedQueue) {
		this.sharedQueue = sharedQueue;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println("Produced : " + i);
			try {
				sharedQueue.put(i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

class Consumer implements Runnable {
	private final BlockingQueue<Integer> sharingQueue;

	public Consumer(BlockingQueue<Integer> sharingQueue) {
		this.sharingQueue = sharingQueue;
	}

	@Override
	public void run() {
		while (true) {
			try {
				System.out.println("Consumed : " + sharingQueue.take());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}